package jp.eisbahn.mgapi.api.voice;

import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;

import jp.eisbahn.mgapi.api.NopResponse;
import jp.eisbahn.mgapi.api.Request;
import jp.eisbahn.mgapi.api.Response;
import jp.eisbahn.mgapi.http.ContentType;
import jp.eisbahn.mgapi.http.HttpMethod;

/**
 * The request class to access to the Voice API.
 * @author Yoichiro Tanaka
 */
public class VoiceRequest implements Request {

    /** Base url to get the user's timeline. */
    private static final String GET_USER_TIMELINE_BASE_URI =
        "/voice/statuses/{userId}/user_timeline";
    /** Base url to get the friend's timeline. */
    private static final String GET_FRIENDS_TIMELINE_BASE_URI =
        "/voice/statuses/friends_timeline/{groupId}";
    /** Bae url to get a status. */
    private static final String GET_STATUS_BASE_URI =
        "/voice/statuses/{postId}";
    /** Base url to get replies. */
    private static final String GET_REPLIES_BASE_URI =
        "/voice/replies/{postId}";
    /** Base url to get favorites. */
    private static final String GET_FAVORITES_BASE_URI =
        "/voice/favorites/{postId}";
    /** Base url to post a status. */
    private static final String POST_STATUS_BASE_URI = "/voice/statuses";
    /** Base url to post a reply. */
    private static final String POST_REPLY_BASE_URI = "/voice/replies/{postId}";
    /** Base url to post a favorite. */
    private static final String POST_FAVORITE_BASE_URI =
        "/voice/favorites/{postId}";
    /** Base url to delete a status. */
    private static final String DELETE_STATUS_BASE_URI =
        "/voice/statuses/{postId}";
    /** Base url to delete reply. */
    private static final String DELETE_REPLIES_BASE_URI =
        "/voice/replies/{postId}/{commentId}";
    /** Base url to delete favorite. */
    private static final String DELETE_FAVORITE_BASE_URI =
        "/voice/favorites/{postId}/{userId}";

    /** The user ID. */
    private String userId;
    /** The group ID. */
    private String groupId = "";
    /** The post ID. */
    private String postId;
    /** The comment ID. */
    private String commentId;
    /** The request type. */
    private RequestType requestType;
    /** The status string. */
    private String status;
    /** The text string. */
    private String text;

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getUri()
     */
    @Override
    public final String getUri() {
        if (requestType == RequestType.GET_USER_TIMELINE) {
            return GET_USER_TIMELINE_BASE_URI.replace("{userId}", userId);
        } else if (requestType == RequestType.GET_FRIENDS_TIMELINE) {
            return GET_FRIENDS_TIMELINE_BASE_URI.replace("{groupId}", groupId);
        } else if (requestType == RequestType.GET_STATUS) {
            return GET_STATUS_BASE_URI.replace("{postId}", postId);
        } else if (requestType == RequestType.GET_REPLIES) {
            return GET_REPLIES_BASE_URI.replace("{postId}", postId);
        } else if (requestType == RequestType.GET_FAVORITES) {
            return GET_FAVORITES_BASE_URI.replace("{postId}", postId);
        } else if (requestType == RequestType.POST_STATUS) {
            return POST_STATUS_BASE_URI;
        } else if (requestType == RequestType.POST_REPLY) {
            return POST_REPLY_BASE_URI.replace("{postId}", postId);
        } else if (requestType == RequestType.POST_FAVORITE) {
            return POST_FAVORITE_BASE_URI.replace("{postId}", postId);
        } else if (requestType == RequestType.DELETE_STATUS) {
            return DELETE_STATUS_BASE_URI.replace("{postId}", postId);
        } else if (requestType == RequestType.DELETE_REPLY) {
            return DELETE_REPLIES_BASE_URI.replace("{postId}", postId)
                    .replace("{commentId}", commentId);
        } else if (requestType == RequestType.DELETE_FAVORITE) {
            return DELETE_FAVORITE_BASE_URI.replace("{postId}", postId)
                    .replace("{userId}", userId);
        } else {
            throw new IllegalStateException("RequestType not set.");
        }
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getHttpMethod()
     */
    @Override
    public final HttpMethod getHttpMethod() {
        switch(requestType) {
            case GET_USER_TIMELINE:
            case GET_FRIENDS_TIMELINE:
            case GET_STATUS:
            case GET_REPLIES:
            case GET_FAVORITES:
                return HttpMethod.GET;
            case POST_STATUS:
            case POST_REPLY:
            case POST_FAVORITE:
                return HttpMethod.POST;
            case DELETE_STATUS:
            case DELETE_REPLY:
            case DELETE_FAVORITE:
                return HttpMethod.DELETE;
            default:
                throw new IllegalStateException("RequestType not set.");
        }
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getResponseClass()
     */
    @Override
    public final Class<? extends Response> getResponseClass() {
        switch(requestType) {
            case GET_USER_TIMELINE:
            case GET_FRIENDS_TIMELINE:
            case GET_STATUS:
                return VoiceStatusResponse.class;
            case GET_REPLIES:
                return VoiceCommentResponse.class;
            case GET_FAVORITES:
                return VoiceUserResponse.class;
            case POST_STATUS:
            case POST_REPLY:
            case POST_FAVORITE:
            case DELETE_STATUS:
            case DELETE_REPLY:
            case DELETE_FAVORITE:
                return NopResponse.class;
            default:
                throw new IllegalStateException("RequestType not set.");
        }
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getContentType()
     */
    @Override
    public final ContentType getContentType() {
        return ContentType.X_WWW_FORM_URLENCODED;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getParameterMap()
     */
    @Override
    public final Map<String, Object> getParameterMap() {
        Map<String, Object> parameterMap = new HashMap<String, Object>();
        if (requestType == RequestType.POST_STATUS) {
            parameterMap.put("status", status);
        } else if (requestType == RequestType.POST_REPLY) {
            parameterMap.put("text", text);
        }
        return parameterMap;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getBodyStream()
     */
    @Override
    public final InputStream getBodyStream() {
        return null;
    }

    /**
     * Set the user ID.
     * @param newUserId The user ID string.
     */
    public final void setUserId(final String newUserId) {
        userId = newUserId;
    }

    /**
     * Retrieve the user ID.
     * @return The user ID string.
     */
    public final String getUserId() {
        return userId;
    }

    /**
     * Set the group ID.
     * @param newGroupId The group ID.
     */
    public final void setGroupId(final String newGroupId) {
        groupId = newGroupId;
    }

    /**
     * Retrieve the group ID.
     * @return The group ID.
     */
    public final String getGroupId() {
        return groupId;
    }

    /**
     * Set the post ID.
     * @param newPostId The post ID string.
     */
    public final void setPostId(final String newPostId) {
        postId = newPostId;
    }

    /**
     * Retrieve the post ID.
     * @return The post ID.
     */
    public final String getPostId() {
        return postId;
    }

    /**
     * Set the comment ID.
     * @param newCommentId The comment ID.
     */
    public final void setCommentId(final String newCommentId) {
        commentId = newCommentId;
    }

    /**
     * Retrieve the comment ID.
     * @return The comment ID string.
     */
    public final String getCommentId() {
        return commentId;
    }

    /**
     * Set the request type.
     * @param newRequestType The value of the request type.
     */
    public final void setRequestType(final RequestType newRequestType) {
        requestType = newRequestType;
    }

    /**
     * Retrieve the request type value.
     * @return The request type value.
     */
    public final RequestType getRequestType() {
        return requestType;
    }

    /**
     * Set the status.
     * @param newStatus The status string.
     */
    public final void setStatus(final String newStatus) {
        status = newStatus;
    }

    /**
     * Retrieve the status.
     * @return The status string.
     */
    public final String getStatus() {
        return status;
    }

    /**
     * Set the text.
     * @param newText The text string.
     */
    public final void setText(final String newText) {
        text = newText;
    }

    /**
     * Retrieve the text.
     * @return The text string.
     */
    public final String getText() {
        return text;
    }

    /*
     * (non-Javadoc)
     * @see jp.eisbahn.mgapi.api.Request#getHeaderMap()
     */
    @Override
    public final Map<String, String> getHeaderMap() {
        return null;
    }

}
